"use strict";

var path = require('path');
var fs = require('fs');
var crypto = require('crypto');

var gutil = require('gulp-util');
var through = require('through2');

var PLUGIN_NAME = 'gulp-asset-rev';

var ASSET_REG = {
    "SCRIPT": /(<script[^>]+src=)['"]([^'"]+)["']/ig,
    "STYLESHEET": /(<link[^>]+href=)['"]([^'"]+)["']/ig,
    //"IMAGE": /(<img[^>]+src=)['"]([^'"]+)["']/ig,
    "BACKGROUND": /(url\()(?!data:|about:)([^)]*)/ig
};

var createHash = function (file, len) {
    return crypto.createHash('md5').update(file).digest('hex').substr(0, len);
};

var splitJSInHtml = function (file, content, filePath, options) {

    //js content arrry [0]: whole js content, [3]: content without js tag
    var patArray = /(<script[^>]+id=)['"]([^'"]+)["']>([.\S\s]*?)(<\/script>)/i
    //whole js content include <script id='123'>XXX</script>
    var patWhole = /(<script[^>]+id=)['"]([^'"]+)["'](>[.\S\s]*?)(<\/script>)/ig

    //js content arrry [0]: whole js content, [2]: content without js tag
    var patArrayWithoutTag = /(<script>)([.\S\s]*?)(<\/script>)/i
    //whole js content include <script>XXX</script>
    var patWholeWithoutTag = /(<script>[.\S\s]*?<\/script>)/ig

    var matchArr = content.match(patArrayWithoutTag);
    if (matchArr == null || matchArr == undefined || matchArr == "" || matchArr.length == 0 || matchArr.length < 2)
        return content;
    var newContent = matchArr[2];
    var path = options.rootPath == "" || options.rootPath == undefined ? filePath : options.rootPath;
    var name = file.path.replace(path, "");
    name = name.substr(name.lastIndexOf("\\") + 1, name.length).replace(".html", "") + "_" + name.length + ".js";
    var newPath = "\\static\\js\\self\\" + name;
    var newName = "/static/js/self/" + name;
    var fileJS = file;
    fileJS.filePath = path + newPath;
    content = content.replace(patWholeWithoutTag, "<script src=\"" + newName + "\"></script>");

    fileJS.contents = new Buffer(newContent);
    //fs.writeFile(fileJS.filePath, fileJS.contents, function (err) {
    //    if (err) throw err;
    //    //console.log("Export Success!");
    //});

    fs.writeFileSync(fileJS.filePath, fileJS.contents);

    return content;
}


module.exports = function (options) {
    return through.obj(function (file, enc, cb) {

        options = options || {};

        if (file.isNull()) {
            this.push(file);
            return cb();
        }

        if (file.isStream()) {
            this.emit('error', new gutil.PluginError(PLUGIN_NAME, 'Streaming not supported'));
            return cb();
        }

        var content = file.contents.toString();

        var filePath = path.dirname(file.path);

        content = splitJSInHtml(file, content, filePath, options);

        for (var type in ASSET_REG) {
            if (type === "BACKGROUND" && !/\.(css|scss|less)$/.test(file.path)) {

            } else {
                content = content.replace(ASSET_REG[type], function (str, tag, src) {
                    src = src.replace(/(^['"]|['"]$)/g, '');

                    if (!/\.[^\.]+$/.test(src)) {
                        return str;
                    }
                    if (options.verStr) {
                        src += options.verStr;
                        return tag + '"' + src + '"';
                    }

                    // remote resource
                    if (/^https?:\/\//.test(src)) {
                        return str;
                    }

                    var assetPath = options.rootPath == "" || options.rootPath == undefined ? path.join(filePath, src) : path.join(options.rootPath, src);
                    //var assetPath = path.join(filePath, src);

                    if (src.indexOf('/') == -1) {
                        if (options.resolvePath && typeof options.resolvePath === "function") {
                            assetPath = options.resolvePath(src);
                        } else {
                            assetPath = (options.rootPath || "") + src;
                        }
                    }

                    if (fs.existsSync(assetPath)) {

                        var buf = fs.readFileSync(assetPath);

                        var md5 = createHash(buf, options.hashLen || 7);

                        //var verStr = (options.verConnecter || "-") + md5;

                        //src = src.replace(verStr, '').replace(/(\.[^\.]+)$/, verStr + "$1");
                        var verStr = (options.verConnecter || "") + md5;
                        src = src + "?v=" + verStr;
                    } else {
                        return str;
                    }

                    return tag + '"' + src + '"';
                });
            }
        }

        file.contents = new Buffer(content);
        this.push(file);
        cb();
    });
};

